package com.yunchmall.gateway.filter;


import com.yunchmall.gateway.client.AuthServiceClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * @author Liangyaoyun
 */
//第一步：声明一个Filter类，实现GlobalFilter接口
@SuppressWarnings("all")
@Service
@ConfigurationProperties("auth-filter")
//第三步:将这个类注入Spring的bean容器
//对token进行验证，在网关中实现统一的权限认证
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    //包含放行的请求
    private List<String> excludes;
    //设计一个基于配置文件的开关
    public boolean enabled;

    public void setExcludes(List<String> excludes) {
        this.excludes = excludes;
    }

    @Autowired
    public AuthServiceClient authService;

    //第二步：重写Filter方法
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        if (!enabled) {
            return chain.filter(exchange);
        }
        String uri = exchange.getRequest().getURI().getPath();
        //如果在白名单里面则直接跳过鉴权操作
        if (excludes.contains(uri)) {
            return chain.filter(exchange);
        }
        //Authorization从请求头中获取要包含token令牌
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        //没找到token
        //token过期
        //token是伪造的
        if (token == null || authService.auth(token) == null) {
            //401
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);// 401
            //响应结束,方法终止
            return exchange.getResponse().setComplete();
        } else {
            return chain.filter(exchange);
        }
    }


    //保证我们自定义的过滤器位于整个过滤器的最前端
    @Override
    public int getOrder() {
        return 1;
    }

}
